package MotorMySql;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import MotorMySql.AccesoDisco;
import MotorMySql.Queries;
import MotorMySql.SQLIException;

public class MotorMySQL {
	public List<String> ejecutarQuery(Queries query) throws SQLIException {
		ArrayList<String> resultado = new ArrayList<String>();

		try{
		// Lee todos los registros del archivo.
		AccesoDisco accesoDisco = new AccesoDisco();
		List<Object> registros = accesoDisco.leerRegistros(query.getTabla());

		// Recorre todos los registros que leyo utilizando un for each.
		for (Object registro : registros) {
			// Obtiene el valor del atributo
			Object valorCampo = getValor(registro, query);

			// Agrega el valor a la lista de resultados, si es nulo agraga la palabra "Null"
			if (valorCampo == null) {
				resultado.add("NULL");
			} else {
				resultado.add(valorCampo.toString());
			}
		}
		}catch(SQLIException sql){
			throw sql;
		}catch(Exception e){
			throw new SQLIException("Se produjo un error no contemplado al intentar ejecutar la consulta.");
		}
		

		return resultado;
	}

	private Object getValor(Object registro, Queries query) throws SQLIException {
		Object valor = null;

		try {
			// Compara que el nombre del tipo de dato sea igual al nombre de la
			// "tabla"
			if (registro.getClass().getName().equalsIgnoreCase(query.getTabla())) {

				/**
				 * Busca dentro de la deficinion del objeto el atributo que
				 * coincida con el nombre del campo en la consulta
				 */
				String nombreAtributo = query.getCampo();
				Field atributo = registro.getClass().getDeclaredField(nombreAtributo);

				/**
				 * Marca al atributo como publico, rompiendo la encapsulacion:
				 * en lugar de acceder al estado a travez de las propiedades lo
				 * hace directamente sobre el atributo.
				 */
				atributo.setAccessible(true);
				valor = atributo.get(registro);
			}

		}
		//Captura las excepciones y las relanza con un mensaje amigable.
		catch(NoSuchFieldException ns){
			String mensaje = "No se encontro el campo: " + query.getCampo() + " en la tabla: " + query.getTabla();
			throw new SQLIException(mensaje);
		}
		catch (Exception e) {
			throw new SQLIException("Se produjo un error inesperado al intentar leer el valor del registro.", e);
		}
		return valor;
	}

}
